package spark.network;

import spark.network.ServerConnection;
import spark.network.protocol.*;

import org.apache.log4j.Logger;
import spark.network.strategy.ClockAdjustNoticeStrategy;
import spark.network.strategy.ClockSyncReqStrategy;
import spark.network.strategy.PreLoginResponseStrategy;

import java.net.InetSocketAddress;

public abstract class ClientDemonHandler extends spark.network.DemonHandler<ServerConnection> {
	private static Logger logger = Logger.getLogger(ClientDemonHandler.class);

	private ClockSyncReqStrategy clockSyncReqStrategy;
	private ClockAdjustNoticeStrategy clockAdjustNoticeStrategy;
	private PreLoginResponseStrategy preLoginResponseStrategy;

	protected ClientDemonHandler(ServerConnection serverConnection, Sender sender) {
		super(serverConnection, sender);
		preLoginResponseStrategy = new PreLoginResponseStrategy(connections);
		clockSyncReqStrategy = new ClockSyncReqStrategy();
		clockAdjustNoticeStrategy = new ClockAdjustNoticeStrategy(this);
	}

	public void setPreLoginResponseListener(IPreLoginResponseResultListener preLoginResponseListener) {
		preLoginResponseStrategy.setPreLoginResponseListener(preLoginResponseListener);
	}

	public void handle(ClockSyncReq clockSyncReq, InetSocketAddress source) {
		super.handle(clockSyncReq, source, clockSyncReqStrategy);
	}

	public void handle(ClockAdjustNotice clockAdjustNotice, InetSocketAddress source) {
		super.handle(clockAdjustNotice, source, clockAdjustNoticeStrategy);
	}

	public void handle(PreLoginResponse preLoginResponse, InetSocketAddress source) {
		preLoginResponse.setSource(source);
		super.handle(preLoginResponse, source, preLoginResponseStrategy);
	}

	//---------> all this has been moved to be handled by higher order logic or PreLoginResponseStrategy
	//	/**
//	 * Properly initializes networking components based on the preLoginResponse.
//	 * @param preLoginResponse Response to handle.
//	 * @param source Source this response was received from.
//	 * @return true if the PreLogin was successfull. false otherwise.
//	 */
//	public boolean handle(PreLoginResponse preLoginResponse, InetSocketAddress source) {
//		Base packetRespondedTo = sender.updateAwaitingConfirmations(preLoginResponse);
//		//if we were not waiting for a response or the response was bogus
//		if(packetRespondedTo == null) {
//			logger.warn("Received an invalid response of type PreLoginResponse. No response was awaited.");
//			if(preLoginResponseListener != null) {
//				preLoginResponseListener.preLoginFailed("Received a connection response but no connection request was found.");
//			}
//			return false;
//		}
//		//this is now handled by the sender
///*		if(!(packetRespondedTo instanceof PreLogin)) {
//			logger.warn("Received an invalid response of type PreLoginResponse. Response matched a packet but that packet was of type: " + packetRespondedTo.getClass() + ".");
//			if(preLoginResponseListener != null) {
//				preLoginResponseListener.preLoginFailed("Connection response received did not match a valid connection request.");
//			}
//			return false;
//		}*/
//		PreLogin preLogin = (PreLogin) packetRespondedTo;
//		//if the response's validation did not match that of our request
//		if(preLoginResponse.getValidation() != preLogin.getValidation()) {
//			logger.error("Received an invalid PreLoginResponse, original validation of " + preLogin.getValidation() + " was unmatched by the response's validation " + preLoginResponse.getValidation());
//			if(preLoginResponseListener != null) {
//				preLoginResponseListener.preLoginFailed("Connection response contained an invalid validation.");
//			}
//			return false;
//		}
//
//		if(!preLoginResponse.getAccepted()) {
//			logger.info("Server did not accept the PreLogin reason given: " + new String(preLoginResponse.getMessage()));
//			if(preLoginResponseListener != null) {
//				preLoginResponseListener.preLoginFailed("Server denied connection. Reason: " + new String(preLoginResponse.getMessage()));
//			}
//			return false;
//		}
//
//		NetworkConnection server = connections.getConnection(NetworkConnection.SESSION_UNESTABLISHED);
//		if(server == null) {
//			logger.error("Could not fetch the server, it seems that a prelogin already occured and a session was handed out");
//			if(preLoginResponseListener != null) {
//				preLoginResponseListener.preLoginFailed("Valid connection response received from server however no connection object for the server was found.");
//			}
//			return false;
//		}
//		server.setSession(preLoginResponse.getSession());
//		server.setAddress(source);
//		if(preLoginResponseListener != null) {
//			preLoginResponseListener.preLoginSucceeded();
//		}
//		return true;
//	}
}